import os,threading
import ctypes,time
import datetime

import win32gui
from frame.TaskBarIcon import TaskBarIcon
from PIL import ImageTk

import ttkbootstrap as ttk
from ttkbootstrap.constants import *

from tkinter import messagebox as box
from tkinter.filedialog import askdirectory,askopenfilename

from util.configUtil import ConfigUtil
from frame.core import BackgroundForm,SetForm
from frame.tab import fanjuTab,applicationTab
from frame.win import infoWin
from frame.destop import cat
import util.logUtil as logUtil

from pynput import keyboard

'''
程序入口
'''
class main_frame():

    def __init__(self) -> None:
        self.path=os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + os.path.sep + ".")  #获取文件路径

        self.win = ttk.Window("tk-tool", "journal",iconphoto=self.path+"/icon/tool.png")

        self.initImg()

        self.config=ConfigUtil(self.path)
        self.data=self.config.read()
        self.log=logUtil.getDayLog(filename="info.log")

        #默认是否显示窗口
        if self.data['showMain'] ==1:
            self._close()

        #快捷键
        self.listener=self.start_keyboard_listen()
        #初始化窗口
        self.center_window()

        #打开桌宠
        self.cat=cat(self)

        # 标签页
        self.notebook = ttk.Notebook(self.win)
        self.notebook.pack(expand=True,fill=BOTH)
        # self.notebook.bind('<<NotebookTabChanged>>', self.on_tab_change)
        
        #番剧
        self.fanju=fanjuTab(self)
        self.application=applicationTab(self)

        #设置定时任务和托盘
        self.initSet()

        #标签
        self.setNote()
        
        # 信息窗
        self.infoWin=infoWin(self)

        #开启锁屏效验
        self.win.after(1000, self.checkBgk)
        self.win.mainloop()

    def checkBgk(self):
        '''
        定时任务
        '''
        if self.data["state"] ==1:
            return
            
        timeNow=datetime.datetime.now()
        if timeNow.minute==self.data['start'] and not self.state and not self.headState:  #锁屏
            self.state=True
            self.active_open_win(state=1)

        elif timeNow.minute==self.end and self.state:  #解除锁屏
            self.close_win()

        # elif timeNow.hour>=22 and not self.state:   #休息
        #     self.active_open_win(1)
        self.win.after(1000, self.checkBgk)
    
    def active_open_win(self,state=0):
        '''
        开启锁屏
        state 0 手动锁屏 1 定时锁屏
        '''
        if state==0:
            self.headState=True

        # print("开","定时:",self.state,"手动",self.headState)
        self.closeWin = ttk.Toplevel(self.win)
        self.closeWin.attributes("-fullscreen", True) #全屏
        self.closeWin.attributes("-topmost", True)  #窗口在最高层
        self.closeWin.protocol("WM_DELETE_WINDOW", self.active_close_win)
        self.closeWin.wm_attributes("-alpha", 0.5)        # 透明度(0.0~1.0)
        BackgroundForm(self,state=state)

    def active_close_win(self):
        '''
        主动关闭锁屏
        '''
        if self.headState:
            self.headState=False
        self.closeWin.destroy()
        # print("开","定时:",self.state,"手动",self.headState)
        

    def close_win(self):
        '''
        定时关闭锁屏锁屏
        '''
        if self.state:
            self.state=False
        self.active_close_win()

    def setNote(self):
        '''
        设置
        '''
        self.set_tab = SetForm(self)
        self.notebook.add(self.set_tab, text='设置')

    # def on_tab_change(self,event):
    #     tab = event.widget.tab('current')['text']
    #     if tab == '设置':
    #         self.set_tab.init()

    def changeValue(self,data):
        '''
        修改设置值
        '''
        self.config.write(data)
        self.data=data
        #更新锁屏监控时间
        self.end=self.data['start']+self.data['step']
        
        box.showinfo(
                title='提醒', 
                message="修改成功！"
            )

        #重绘布局
        self.set_tab.init()

    # 按下键盘事件
    def on_press( self,key):
        if key ==keyboard.Key.f3:
            # self.openInfo()
            self._command("cmd")

    def start_keyboard_listen(self):
        listener = keyboard.Listener(
            on_press=self.on_press)
        listener.start()
        return listener

    def initSet(self):
        #锁屏设置
        self.end=self.data['start']+self.data['step']
        self.state=False
        self.headState=False

        if self.data['openIcon'] ==0:
            # 打开托盘
            self.backend_thread = threading.Thread(target=self.backend)
            self.backend_thread.setDaemon(True)
            self.backend_thread.start()

            # 窗口关闭
            self.win.protocol("WM_DELETE_WINDOW", self._close)


    def initImg(self):
        PATH=self.path+"/image/"
        # self.images = [
        #     ttk.PhotoImage(
        #         name='registry',
        #         file=PATH + 'icons8_registry_editor_64px.png'),
        # ]

    def exit(self):
        '''
        退出
        '''
        self.listener.stop()
        # 退出 TaskBarIcon
        win32gui.DestroyWindow(self.t.hwnd)

        self.cat._quit()
        # 退出 Tkinter
        self.win.destroy()

    def _close(self):
        '''
        关闭窗口
        '''
        # windows 系统消息
        #self.t.ShowToast(title="最小化", msg="窗口已经最小化到图标")
        self.win.withdraw()

    def _print(self):
        print("点击")

    def _show(self):
        '''
        激活窗口
        '''
        self.notebook.select(0)
        self.win.deiconify()

    # def _left_click(self, *args):
        # '''
        # 单击托盘
        # '''
        # print("_left_click 接收参数:", args)

    def _openDir(self,*args):
        path=''.join(args)
        if not os.path.exists(path):
            box.showwarning(
                title='提醒', 
                message="目标 "+path+" 不存在"
            )
        else:
            self._command(path)
    
    def _system(self,*args):
        cmd=''.join(args)
        self._command(cmd)
        

    def _command(self,cmd):
        os.system('start '+cmd)

    def _share(self):
        '''
        共享文件
        '''
        path= askdirectory()
        if path and len(path)>0:
            path = path.replace("/", "\\")
            os.system('start python -m http.server 8080 --directory '+path)
            url='http://'+self.getIp()+':8080'
            os.system('start '+url)
            self.showCode(url)

    def getIp(self):
        import socket
        # 函数 gethostname() 返回当前正在执行 Python 的系统主机名
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        return s.getsockname()[0]

    def _about(self):
        box.showinfo(title='关于',message="wzh桌面工具(2022-"+str(time.localtime(time.time())[0])+")")

    def errMsg(self,msg=""):
        box.showinfo(title='关于',message="操作"+msg+"异常")
    
    def openInfo(self):
        '''
        显示信息窗
        '''
        self.infoWin._show()
    
    def md5File(self):
        '''
        获取文件md5值
        '''
        path= askopenfilename()
        if path and len(path)>0:
            import hashlib
            with open(path, 'rb') as f:
                md5Value=hashlib.md5(f.read()).hexdigest()
                #复制内容到剪切板
                # import pyperclip 
                # pyperclip.copy(md5Value)
                self.win.clipboard_clear()
                self.win.clipboard_append(md5Value)
                
                box.showinfo(
                    title='结果已复制剪切板', 
                    message=path+" md5值 "+md5Value
                )

    def dataShow(self):
        '''
        网址二维码显示
        '''
        #提取剪切板数据
        data=self.win.clipboard_get()
        if len(data)>0:
            self.showCode(data)

    def showCode(self,url,title='文件夹共享'):
        import qrcode
        qr = qrcode.QRCode(
            version=2,
            error_correction=qrcode.constants.ERROR_CORRECT_L,
            box_size=10,
            border=1
        )#设置二维码的大小
        qr.add_data(url)
        qr.make(fit=True)

        img = qr.make_image()
        codeWin = ttk.Toplevel(self.win)
        codeWin.wm_title(title )

        width=500
        height=500
        screenwidth = self.win.winfo_screenwidth()
        screenheight = self.win.winfo_screenheight()
        
        size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 3)
        codeWin.geometry(size)  #初始化宽高和位置
        # codeWin.resizable(width=False, height=False)#禁止改变窗口大小
        codeWin.wm_attributes("-topmost", True) #至于最顶部
        codeWin.update()

        self.photo = ImageTk.PhotoImage(img)
        image_Label = ttk.Label(codeWin, image=self.photo)
        image_Label.pack(padx=0,pady=0)
        # codeWin.mainloop()

    def getWeek(self):
        import calendar,datetime
        currentdate = datetime.date.today()
        return calendar.weekday(currentdate.year,currentdate.month,currentdate.day)+1  #周一 0 周五 4

    def backend(self):
        '''
        定义托盘
        '''
        self.t = TaskBarIcon(
            # left_click=(self._left_click, (1, 2)),  # 左键单击回调函数,可以不设置(如果想要传参,这样写(func,(arg1,arg2)))
            double_click=self._show,  # 左键双击回调函数,可以不设置(如果不想传参,直接写函数名称)
            icon=self.path+"/icon/main.ico",  # 设置图标,可以不设置
            hover_text="tk-tool",  # 设置悬浮在小图标显示的文字,可以不设置
            menu_options=[  # 可以不设置
                ['退出', self.path+"/icon/退出.ico", self.exit, 1],  # 菜单项格式:["菜单项名称","菜单项图标路径或None",回调函数或者子菜单列表,id数字(随便写不要重复即可)]
                ['关于', self.path+"/icon/about.ico", self._about, 5],  
                ["分隔符", None, None, 7],
                ["系统服务",  self.path+"/icon/system.ico", [
                    ['重启桌面', None, (self._system,"cmd /c  taskkill /f /im explorer.exe & start explorer"), 116],
                    ['系统服务(services.msc)', None, (self._system,"services.msc"), 115],
                    ['组策略(gpedit.msc)', None, (self._system,"gpedit.msc"), 119],
                    ['系统属性(sysdm.cpl)', None, (self._system,"sysdm.cpl"), 120],
                    ['注册表(regedit)', None, (self._system,"regedit"), 114],
                    ['卸载程序', None, (self._system,"rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl"), 113],
                    ['画板(mspaint)', None, (self._system,"mspaint"), 123],
                    ['计算器(calc)', None, (self._system,"calc"), 112],
                    ['截图', None, (self._system,"snippingtool"), 118],
                    ['hosts', None, (self._openDir,"C:\\Windows\\System32\\drivers\\etc"), 292],
                    ['开机启动', None, (self._openDir,"C:\ProgramData\Microsoft\Windows\StartM~1\Programs\StartUp"), 24],
                    ['设备管理器', None, (self._system,"devmgmt.msc"), 122],
                    ['控制面板(control)', None, (self._system,"control"), 121],
                    ['cmd(F3)', None, (self._system,"cmd"), 117],
                    ['mstsc', None, (self._system,"mstsc"), 111],
                ],11],
                # ['信息窗', None, self.openInfo, 14],  
                ['管理壁纸',  self.path+"/icon/pic.ico", (self._openDir,self.path+"/image/bgk/"), 8],
                ['共享文件夹', self.path+"/icon/share.ico", self._share, 9],  
                ['文件md5值', self.path+"/icon/md5.ico", self.md5File, 16],  
                ['一键启动', self.path+"/icon/启动.ico", self.application.startAll, 13],
                ["分隔符", None, None, 12],
                ["自定义菜单",  self.path+"/icon/more.ico", [
                    ['照片', None, (self._openDir,"D:\\picture"), 27],
                    ['壁纸', None, (self._openDir,"C:\\Users\\wangzonghui\\AppData\\Roaming\\Microsoft\\Windows\\Themes"), 29],
                    ['联想壁纸', None, (self._openDir,"C:\\ProgramData\\Lenovo\\devicecenter\\LockScreen"), 291],
                    ['安装包', None, (self._openDir,"D:\\工作文件\\安装包\\"), 292],
                    ['工作文件', None, (self._openDir,"D:\\工作文件\\工作任务\\"+str(time.localtime(time.time())[0]-2000)+"年"), 28],
                ],6],
                ['小猫', self.path+"/icon/cat.ico", self.cat.change, 15],  
                ['内容转二维码', self.path+"/icon/code.ico", self.dataShow, 30],  
                ['今日番剧', self.path+"/icon/日历.ico", self.fanju.openComic, 3],
                ['锁屏', self.path+"/icon/等待文件.ico", self.active_open_win, 4],
                ['主页', self.path+"/icon/主页.ico", self._show, 2],
            ],
            menu_style="iconic",  # 设置右键菜单的模式,可以不设置:normal(不展示图标),iconic(展示图标)
            icon_x_pad=12,  # 设置图标左边距
            main=self  # 添加主窗口引用
        )
        # 注意这是死循环，类似与tkinter中的mainloop,
        # 因为都是死循环,所以与mainloop会冲突,放到线程里面执行.
        win32gui.PumpMessages()


    def center_window(self, win=None,width=0, height=0):
        '''
        定义窗口
        '''
        if not win:
            win=self.win
        
        screenwidth = win.winfo_screenwidth()
        screenheight = win.winfo_screenheight()
        
        if width==0:
            width=int(screenwidth*0.6)
            height=int(screenheight*0.8)
        
        size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 3)
        win.geometry(size)  #初始化宽高和位置
        # win.minsize(width, height) # 最小宽高
        win.resizable(width=False, height=False)#禁止改变窗口大小

        ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('any')

        # self.win.attributes("-fullscreen", True)  #窗口最大化
        # self.win.iconbitmap('panda.ico')   # 更改窗口图标 仅支持ico
        # self.win.overrideredirect(1)                 # 去除窗口边框
        # self.win.wm_attributes("-alpha", 0.8)        # 透明度(0.0~1.0)
        # self.win.wm_attributes("-toolwindow", True)  # 置为工具窗口(没有最大最小按钮)
        # self.win.wm_attributes("-topmost", True)     # 永远处于顶层
        # self.win.iconphoto(False, tk.PhotoImage(file=self.path+"/icon/tool.png"))   # 更改窗口图标 仅支持png
        # self.win.iconphoto(True, PhotoImage(master=self, data='base64值'))
        win.update()

if __name__ == '__main__':
    main_frame()